/*
 * MyExceptioh.h
 *
 * $Id: MyException.h,v 1.9 2000/05/26 10:09:48 dms Exp $
 *
 */


#ifndef myexception_h
#define myexception_h

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

// #define SYSLOG_EXCEPTION

#ifdef SYSLOG_EXCEPTION
# include <syslog.h>
# define  LOG syslog
# define  L_NOTICE LOG_NOTICE
# define  L_DEBUG  LOG_DEBUG
# define  L_ERR    LOG_ERR
#else
# define LOG fprintf
# define L_NOTICE stderr
# define L_DEBUG  stderr
# define L_ERR    stderr
#endif

#ifndef MAX_EX_MESSAGE
# define MAX_EX_MESSAGE  512
#endif

#ifndef MAX_EX_TYPE
# define MAX_EX_TYPE  64
#endif

#ifndef MAX_EX_FILE
# define MAX_EX_FILE 256
#endif

#ifndef TMP_PATH
# define TMP_PATH "/var/tmp"
#endif

/*
#ifdef __GNUC__
# define va_call(last) ((va_list)__builtin_next_arg(last))
#else
# define va_call(last)  ((va_list)&(last) + __va_size(last))
# endif
#endif
*/

#ifndef NO_STL
#include <string>
#endif

#define DECLARE_EXCEPTION(tag) class  tag##Exception:public MyException\
                        { public:\
                             tag##Exception(){}\
                             tag##Exception(const char *format, ... )\
                               { va_list ap; va_start(ap, format); fire(#tag, (char *) format, ap); va_end(ap); }\
                        }


#define DECLARE_EXCEPTION2(tag, parent) class  tag##Exception:public parent##Exception\
                        { public:\
                             tag##Exception(const char *format, ... )\
                               { va_list ap; va_start(ap, format); fire(#tag, (char *) format, ap); va_end(ap); }\
                        }


class MyException
    {
    public:
      char _tag[MAX_EX_TYPE+1];
      char _message[MAX_EX_MESSAGE+1];

      MyException(){ }
      MyException(char * tag, char *format, ... );
      void fire(char * tag, char *format, va_list ap );

#ifdef SYSLOG_EXCEPTION
     ~MyException(){ closelog(); }
#endif

     void print()
      {  fprintf(stderr,"%s# %s\n",_tag, _message);
#ifdef SYSLOG_EXCEPTION
         syslog(LOG_ERR, _message);
#endif
      }
#ifndef NO_STL
     std::string what() const
     {
       std::string res(_tag);
       res.append(":");
       res.append(_message);
       return res;
     }
#endif

     int operator ==(char *val){ return (strcmp(_tag,val) == 0); }
  };


void __sighandler(int sig);
void set_sighandler(char *pname);

#ifdef HAVE_STL_STRING
inline ostream &operator<<(ostream &stream, MyException &e)
    { return (stream << e._tag << '#' << e._message);
    }
#endif

#endif
